home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 17 / CU Amiga Magazine's Super CD-ROM 17 (1997)(EMAP Images)(GB)[!][issue 1997-12].iso / CUCD / Programming / DiceSource / src / das / exp.c < prev    next >
C/C++ Source or Header  |  1997-09-09  |  18KB  |  909 lines

  1. /*
  2.  *    (c)Copyright 1992-1997 Obvious Implementations Corp.  Redistribution and
  3.  *    use is allowed under the terms of the DICE-LICENSE FILE,
  4.  *    DICE-LICENSE.TXT.
  5.  */
  6.  
  7. /*
  8.  *  EXP.C
  9.  */
  10.  
  11. #include "defs.h"
  12.  
  13. Prototype long    ParseIntExp(char *);
  14. Prototype char    *ParseExp(char *, Label **, long *);
  15. Prototype char    *ParseEffAddr(ubyte *, EffAddr *);
  16. Prototype char    *ParseRegList(char *, uword *);
  17. Prototype char    *ParseBinaryConst(char *, long *);
  18. Prototype char    *ParseHexConst(char *, long *);
  19. Prototype char    *ParseIntConst(char *, long *);
  20. Prototype char    *ParseLabel(char *, Label **, int);
  21. Prototype int    CheckRegister(char *);
  22. Prototype void    InitAlNumAry(void);
  23.  
  24. char AlNumAry[256];
  25. char LowerAry[256];
  26.  
  27. void
  28. InitAlNumAry(void)
  29. {
  30.     short i;
  31.  
  32.     for (i = 0; i < 256; ++i)
  33.     LowerAry[i] = i;
  34.  
  35.     for (i = 'a'; i <= 'z'; ++i)
  36.     AlNumAry[i] = 1;
  37.     for (i = 'A'; i <= 'Z'; ++i) {
  38.     AlNumAry[i] = 1;
  39.     LowerAry[i] = 'a' - 'A' + i;
  40.     }
  41.     for (i = '0'; i <= '9'; ++i)
  42.     AlNumAry[i] = 1;
  43.     AlNumAry['_'] = 1;
  44.     AlNumAry['@'] = 1;
  45.  
  46. }
  47.  
  48. long
  49. ParseIntExp(str)
  50. char *str;
  51. {
  52.     long a = 0;
  53.     long v;
  54.     short op = -1;
  55.     short neg = 0;
  56.  
  57.     while (*str && *str != ' ' && *str != 9) {
  58.     if (op) {
  59.         if (*str == '-') {
  60.         neg = !neg;
  61.         ++str;
  62.         continue;
  63.         } else if (*str == '$') {
  64.         str = ParseHexConst(str + 1, &v);
  65.         } else if (*str >= '0' && *str <= '9') {
  66.         str = ParseIntConst(str, &v);
  67.         } else if (*str == '%') {
  68.         str = ParseBinaryConst(str + 1, &v);
  69.         } else {    /*  assume label    */
  70.         Label *lab;
  71.         char *base = str;
  72.         str = ParseLabel(str, &lab, 1);
  73.         if (lab)
  74.             v = lab->l_Value;
  75.         if (base == str) {
  76.             cerror(EERROR_ILLEGAL_LABEL, base);
  77.             ++str;
  78.         }
  79.         }
  80.         if (neg)
  81.         v = -v;
  82.         neg = 0;
  83.         switch(op) {
  84.         case -1:
  85.         a = v;
  86.         break;
  87.         case '+':
  88.         a += v;
  89.         break;
  90.         case '-':
  91.         a -= v;
  92.         break;
  93.         }
  94.         op = 0;
  95.     } else {
  96.         switch(*str) {
  97.         case '+':
  98.         case '-':
  99.         op = *str;
  100.         break;
  101.         default:
  102.         cerror(EERROR_EXPECTED_OPERATOR, *str);
  103.         break;
  104.         }
  105.         ++str;
  106.     }
  107.     }
  108.     if (op)
  109.     cerror(EERROR_EXPECTED_EXP);
  110.  
  111.     return(a);
  112. }
  113.  
  114. /*
  115.  *  Parses an expression filling in the appropriate fields in the
  116.  *  effective address.    Does NOT have to handle registers, register lists,
  117.  *  or addressing modes.
  118.  */
  119.  
  120. char *
  121. ParseExp(str, plab, poff)
  122. char *str;
  123. Label **plab;
  124. long  *poff;
  125. {
  126.     long a = 0;
  127.     long v;
  128.     short op = -1;
  129.     short neg = 0;
  130.  
  131.     while (*str) {
  132.     if (op) {
  133.         if (*str == '-') {
  134.         neg = !neg;
  135.         ++str;
  136.         continue;
  137.         } else if (*str == '$') {
  138.         str = ParseHexConst(str + 1, &v);
  139.         } else if (*str >= '0' && *str <= '9') {
  140.         str = ParseIntConst(str, &v);
  141.         } else if (*str == '%') {
  142.         str = ParseBinaryConst(str + 1, &v);
  143.         } else {    /*  assume label    */
  144.         Label *lab;
  145.         char *base = str;
  146.  
  147.         v = 0;
  148.         str = ParseLabel(str, &lab, 1);
  149.         if (lab) {
  150.             dbprintf(0, ("exp lab %s type %d val %ld\n", lab->Name, lab->l_Type, lab->l_Value));
  151.             switch(lab->l_Type) {
  152.             case LT_LOC:
  153.             case LT_EXT:
  154.             *plab = lab;
  155.             if (op == '-' || neg)
  156.                 cerror(EERROR_NEG_LABEL_OFFSET);
  157.             break;
  158.             case LT_REG:
  159.             *plab = lab;
  160.             break;
  161.             case LT_INT:
  162.             v = lab->l_Value;
  163.             break;
  164.             }
  165.         } else {
  166.             dbprintf(0, ("Label %s not found\n", str));
  167.         }
  168.         if (base == str) {
  169.             cerror(EERROR_ILLEGAL_LABEL, base);
  170.             ++str;
  171.         }
  172.         }
  173.         if (neg)
  174.         v = -v;
  175.         neg = 0;
  176.  
  177.         switch(op) {
  178.         case -1:
  179.         a = v;
  180.         break;
  181.         case '+':
  182.         a += v;
  183.         break;
  184.         case '-':
  185.         a -= v;
  186.         break;
  187.         }
  188.         op = 0;
  189.     } else {
  190.         switch(*str) {
  191.         case '+':
  192.         case '-':
  193.         op = *str;
  194.         break;
  195.         case '.':
  196.         case ',':
  197.         case '(':
  198.         case ')':
  199.         case '[':
  200.         case ']':
  201.         *poff = a;
  202.         return(str);
  203.         default:
  204.         cerror(EERROR_EXPECTED_OPERATOR, *str);
  205.         break;
  206.         }
  207.         ++str;
  208.     }
  209.     while (*str == ' ' || *str == 9)    /*  XXX remove me? */
  210.         ++str;
  211.     }
  212.     if (op)
  213.     cerror(EERROR_EXPECTED_EXP);
  214.  
  215.     *poff = a;
  216.     return(str);
  217. }
  218.  
  219.  
  220. /*
  221.  *  Parse an addressing mode.
  222.  *
  223.  *    Dn
  224.  *    An
  225.  *    (An)
  226.  *    (An)++
  227.  *    --(An)
  228.  *    exp(An)                 od([bd,An],Xn.size*SCALE)
  229.  *    exp(An,Xn.size*SCALE)   od([bd,An,Xn.size*SCALE])
  230.  *    exp[.size]
  231.  *    exp(pc)
  232.  *    exp(pc,Xn.size*SCALE)
  233.  *    #immediate
  234.  *    CCR
  235.  *    SR
  236.  *    USP
  237.  *
  238.  *    regs    reglist (A single register is a valid reglist)
  239.  *    branch    branch    exp(pc) and exp[.size] (exp contains statement label)
  240.  *            are valid
  241.  */
  242.  
  243. #define MF_MEMIND    0x0001
  244. #define MF_MEMINDPOS    0x0004
  245. #define MF_INDEX    0x0008
  246. #define MF_INDEX020    0x0010
  247. #define MF_BDWORD    0x0020
  248. #define MF_BDLONG    0x0040
  249. #define MF_ODWORD    0x0080
  250. #define MF_ODLONG    0x0100
  251.  
  252. char *
  253. ParseEffAddr(str, ea)
  254. ubyte *str;
  255. EffAddr *ea;
  256. {
  257.     short c1 = str[0];
  258.     short c2 = str[1];
  259.     short c3 = str[2];
  260.     short flags;
  261.     char baseReg;
  262.     char idxReg;
  263.  
  264.     /*
  265.      *    handle simple cases
  266.      */
  267.  
  268.     /*
  269.      *    An
  270.      */
  271.     if (c1 == 'A' && (c2 >= '0' && c2 <= '7') && (c3 == 0 || c3 == ',')) {
  272.     ea->Reg1 = RB_AREG - '0' + c2;
  273.     ea->Mode1 = AB_AN;
  274.     ea->Mode2 = AB_REGS;
  275.     ea->ExtWord |= 1 << ea->Reg1;
  276.     return(str + 2);
  277.     }
  278.  
  279.     /*
  280.      *    Dn
  281.      */
  282.     if (c1 == 'D' && (c2 >= '0' && c2 <= '7') && (c3 == 0 || c3 == ',')) {
  283.     ea->Reg1 = RB_DREG - '0' + c2;
  284.     ea->Mode1 = AB_DN;
  285.     ea->Mode2 = AB_REGS;
  286.     ea->ExtWord |= 1 << ea->Reg1;
  287.     return(str + 2);
  288.     }
  289.  
  290.     /*
  291.      *    handle more complex cases
  292.      */
  293.  
  294.     c1 = LowerAry[c1];
  295.     c2 = LowerAry[c2];
  296.  
  297.     switch(c1) {
  298.     case 'a':
  299.     if (c2 >= '0' && c2 <= '7' && !AlNumAry[c3]) {
  300.         ea->Reg1 = RB_AREG - '0' + c2;
  301.         ea->Mode1 = AB_AN;
  302. anregs:
  303.         ea->Mode2 = AB_REGS;
  304.         ea->ExtWord |= 1 << ea->Reg1;
  305.         str += 2;
  306.         if (c3 == '-' || c3 == '/') {
  307.         ea->Mode1 = AB_REGS;
  308.         ea->Reg1 = -1;
  309.         str = ParseRegList(str-2, &ea->ExtWord);
  310.         }
  311.         return(str);
  312.     }
  313.     break;
  314.     case 'd':
  315.     if (c2 >= '0' && c2 <= '7' && !AlNumAry[c3]) {
  316.         ea->Reg1 = RB_DREG - '0' + c2;
  317.         ea->Mode1 = AB_DN;
  318.         goto anregs;
  319.     }
  320.     break;
  321.     case '(':   /*  (An)[+]     */
  322.     if (c2 == '[')
  323.         break;
  324.     if (str[3] != ')')
  325.         break;
  326.     if (c2 == 's') {
  327.         c2 = 'a';
  328.         str[1] = 'a';
  329.         str[2] = c3 = '7';
  330.     }
  331.     if (c2 != 'a' || c3 < '0' || c3 > '7')
  332.         syntax(2);
  333.     ea->Reg1 = RB_AREG - '0' + c3;
  334.     if (str[4] == '+') {
  335.         ea->Mode1 = AB_INDPP;
  336.         return(str + 5);
  337.     } else {
  338.         ea->Mode1 = AB_INDAN;
  339.         return(str + 4);
  340.     }
  341.     /* not reached */
  342.     case '#':   /*  #exp    */
  343.     ea->Mode1 = AB_IMM;
  344.     ++str;
  345.     break;
  346.     case '-':   /*  -(An)  */
  347.     if (c2 == '(') {
  348.         c1 = str[2] | 0x20;
  349.         c2 = str[3] | 0x20;
  350.         if (c1 == 's' && c2 == 'p') {
  351.         c1 = 'a';
  352.         c2 = '7';
  353.         }
  354.         if (c1 != 'a' || str[4] != ')')
  355.         syntax(3);
  356.         ea->Mode1 = AB_MMIND;
  357.         ea->Reg1 = c2 - '0' + RB_AREG;
  358.         return(str + 5);
  359.     }
  360.     break;
  361.     case 'c':   /*  CCR     */
  362.     if (c2 == 'c' && (c3|0x20) == 'r' && !AlNumAry[(short)str[3]]) {
  363.         ea->Mode1 = AB_CCR;
  364.         return(str + 3);
  365.     }
  366.     break;
  367.     case 's':   /*  SP,SR   */
  368.     if (c2 == 'p' && !AlNumAry[c3]) {   /*  sp  */
  369.         ea->Mode1 = AB_AN;
  370.         ea->Mode2 = AB_REGS;
  371.         ea->Reg1 = 7;
  372.         ea->ExtWord = 1 << ea->Reg1;
  373.         return(str + 2);
  374.     }
  375.     if (c2 == 'r' && !AlNumAry[c3]) {
  376.         ea->Mode1 = AB_SR;
  377.         return(str + 2);
  378.     }
  379.     break;
  380.     case 'u':   /*  USP     */
  381.     if (c2 == 's' && (c3|0x20) == 'p' && !AlNumAry[(short)str[3]]) {
  382.         ea->Mode1 = AB_USP;
  383.         return(str + 3);
  384.     }
  385.     break;
  386.     }
  387.  
  388.     /*
  389.      *    Some kind of expression.  ea->Mode1 might already be set to AB_IMM
  390.      *
  391.      *        68000 format            68020 format
  392.      *
  393.      *        d16(An)                             (d16,An)
  394.      *        d8(An,Xn[.size][*SCALE])            (d8,An,Xn.z*SCALE)
  395.      *        exp[.size]
  396.      *        d16(pc)                             (d16,PC)
  397.      *        d8(pc,Xn[.size][*SCALE])            (d8,PC,Xn.z*SCALE)
  398.      *        #exp
  399.      *                        (bd,An,Xn.z*SCALE)  (od redundant)
  400.      *                        (bd,PC,Xn.z*SCALE)  (od redundant)
  401.      *                        ([bd,PC],Xn.z*SCALE,od)
  402.      *                        ([bd,PC,Xn.z*SCALE],od)
  403.      *                              ^
  404.      *                            ZPC for program-acc/PC=0
  405.      */
  406.  
  407.     c1 = *str;
  408.     if (c1 != '(') {
  409.     str = ParseExp(str, &ea->Label1, &ea->Offset1);    /* can be nil exp */
  410.     c1 = *str;
  411.     }
  412.  
  413.     if (c1 == '.') {
  414.     if (ea->Mode1 == AB_IMM)
  415.         syntax(4);
  416.  
  417.     switch(CToSize(str[1])) {
  418.     case 1:
  419.         ea->ISize |= ISF_BYTEB;
  420.         break;
  421.     case 2:
  422.         ea->ISize |= ISF_ABSW;
  423.         break;
  424.     case 4:
  425.         break;
  426.     }
  427.     str += 2;
  428.     c1 = *str;
  429.     }
  430.     if (c1 != '(') {
  431.     if (ea->Mode1 != AB_IMM) {
  432.         Label *lab = ea->Label1;
  433.  
  434.         ea->Mode1 = (ea->ISize & ISF_ABSW) ? AB_ABSW    : AB_ABSL;
  435.         ea->Mode2 = (ea->ISize & ISF_INSTBYTE)? AB_BBRANCH : AB_WBRANCH;
  436.  
  437.         /*
  438.          *    but wait, exp could have been a reg label specifying
  439.          *    a single register.. valid in normal opcodes.
  440.          */
  441.  
  442.         if (lab && lab->l_Type == LT_REG) {
  443.         if (lab->l_RegNo >= 0) {
  444.             ea->Mode1  = (lab->l_RegNo >= RB_AREG) ? AB_AN : AB_DN;
  445.             ea->Reg1   = lab->l_RegNo;
  446.             ea->Mode2  = AB_REGS;
  447.             ea->ExtWord= lab->l_Mask;
  448.         } else {
  449.             ea->Reg1    = -1;
  450.             ea->Mode1    = AB_REGS;
  451.             ea->ExtWord = lab->l_Mask;
  452.         }
  453.         }
  454.     }
  455.     return(str);
  456.     }
  457.  
  458.     /*
  459.      *    general index format
  460.      *
  461.      *    ([bd,An],Xn ...)        note:   od, An, Xn are optional
  462.      *    ([bd,An,Xn...])
  463.      */
  464.  
  465.     flags = 0;
  466.  
  467.     ++str;
  468.     if (*str == '[') {
  469.     flags |= MF_MEMIND | MF_INDEX | MF_INDEX020;
  470.     ++str;
  471.     }
  472.  
  473.     /*
  474.      *    optional base displacement (Label2,Offset2), or base register
  475.      */
  476.  
  477.     baseReg = CheckRegister(str);
  478.     idxReg = -1;
  479.  
  480.     if (baseReg < 0) {
  481.     {
  482.         str = ParseExp(str, &ea->Label2, &ea->Offset2);
  483.  
  484.         flags |= MF_BDLONG;
  485.         if (ea->Label2 && *str != '.')
  486.         cerror(EERROR_OUTER_DISP_WL);
  487.         if (*str == '.') {
  488.         if ((str[1] | 0x20) == 'w') {
  489.             flags |= MF_BDWORD;
  490.             flags &= ~MF_BDLONG;
  491.         }
  492.         str += 2;
  493.         } else if (ea->Offset2 >= -32768 && ea->Offset2 < 32768) {
  494.         if (ea->Offset2)
  495.             flags |= MF_BDWORD;
  496.         flags &= ~MF_BDLONG;
  497.         }
  498.         if (*str == '(' && strnicmp(str, "(a4)", 4) == 0) {
  499.         ea->ISize |= ISF_BDDREL;    /*    data-relative    */
  500.         str += 4;
  501.         if ((flags & (MF_BDWORD|MF_BDLONG)) == 0)
  502.             flags |= MF_BDWORD;
  503.         }
  504.     }
  505. #ifdef NOTDEF
  506.         str = ParseExp(str, &ea->Label1, &ea->Offset1);
  507.  
  508.         flags |= MF_ODLONG | MF_INDEX;
  509.         if (ea->Label1 && *str != '.' && *str != '(')
  510.         cerror(EERROR_OUTER_DISP_WL);
  511.  
  512.         if (*str == '.') {
  513.         if ((str[1] | 0x20) == 'w') {
  514.             flags |= MF_ODWORD;
  515.             flags &= ~MF_ODLONG;
  516.         }
  517.         str += 2;
  518.         } else if (ea->Offset1 >= -32768 && ea->Offset1 < 32768) {
  519.         if (ea->Offset1)
  520.             flags |= MF_ODWORD;
  521.         flags &= ~MF_ODLONG;
  522.         }
  523.         if (*str == '(' && strnicmp(str, "(a4)", 4) == 0) {
  524.         ea->ISize |= ISF_ODDREL;    /*    data-relative    */
  525.         str += 4;
  526.         if ((flags & (MF_ODWORD|MF_ODLONG)) == 0)
  527.             flags |= MF_ODWORD;
  528.         }
  529.     }
  530. #endif
  531.     flags |= MF_INDEX | MF_INDEX020;
  532.     } else {
  533.     str += 2;
  534.     }
  535.  
  536.     if (*str != ']' && baseReg < 0) {
  537.     /*
  538.      *  expect base register, but could be index register
  539.      */
  540.  
  541.     if (*str == ',')
  542.         ++str;
  543.     else
  544.         syntax(13);
  545.  
  546.     baseReg = CheckRegister(str);
  547.     if (baseReg < 0)
  548.         syntax(10);
  549.     str += 2;
  550.     if (baseReg < RB_AREG || *str == '*' || *str == '.') {
  551.         idxReg = baseReg;
  552.         baseReg = -1;
  553.         goto skip;
  554.     }
  555.     }
  556.  
  557.     if (*str == ']') {
  558.     flags |= MF_MEMINDPOS | MF_INDEX | MF_INDEX020;
  559.     ++str;
  560.     }
  561.  
  562.     /*
  563.      *    optional index register
  564.      */
  565.  
  566.     if (*str == ',') {
  567.     idxReg = CheckRegister(str + 1);
  568.  
  569.     if (idxReg >= 0) {
  570.         str += 3;
  571. skip:
  572.         flags |= MF_INDEX;
  573.  
  574.         if (*str == '.') {
  575.         switch(str[1]) {
  576.         case 'w':
  577.         case 'W':
  578.             break;
  579.         case 'l':
  580.         case 'L':
  581.             ea->ExtWord |= EXTF_LWORD;
  582.             break;
  583.         default:
  584.             syntax(11);
  585.         }
  586.         str += 2;
  587.         }
  588.         if (*str == '*') {
  589.         flags |= MF_INDEX | MF_INDEX020;
  590.  
  591.         switch(str[1]) {
  592.         case '1':
  593.             break;
  594.         case '2':
  595.             ea->ExtWord |= 0x0200;
  596.             break;
  597.         case '4':
  598.             ea->ExtWord |= 0x0400;
  599.             break;
  600.         case '8':
  601.             ea->ExtWord |= 0x0600;
  602.             break;
  603.         }
  604.         str += 2;
  605.         }
  606.     }
  607.     }
  608.     if ((flags & (MF_MEMINDPOS|MF_MEMIND)) == MF_MEMIND) {
  609.     if (*str != ']')
  610.         syntax(16);
  611.     ++str;
  612.     }
  613.  
  614.     /*
  615.      *    outer displacement (illegal if no ind)
  616.      */
  617.  
  618.     if (*str == ',') {      /*  outer displacement  */
  619.     if (!(flags & MF_MEMIND))
  620.         cerror(EERROR_NO_BRACKET_NO_OD);
  621.  
  622.     flags |= MF_INDEX | MF_INDEX020;
  623.     str = ParseExp(str + 1, &ea->Label1, &ea->Offset1);
  624.  
  625.     flags |= MF_ODLONG;
  626.     if (ea->Label1 && *str != '.' && *str != '(')
  627.         cerror(EERROR_OUTER_DISP_WL);
  628.  
  629.     if (*str == '.') {
  630.         if ((str[1] | 0x20) == 'w') {
  631.         flags |= MF_ODWORD;
  632.         flags &= ~MF_ODLONG;
  633.         }
  634.         str += 2;
  635.     } else if (ea->Offset1 >= -32768 && ea->Offset1 < 32768) {
  636.         if (ea->Offset1)
  637.         flags |= MF_ODWORD;
  638.         flags &= ~MF_ODLONG;
  639.     }
  640.     if (*str == '(' && strnicmp(str, "(a4)", 4) == 0) {
  641.         ea->ISize |= ISF_ODDREL;    /*  data-relative   */
  642.         str += 4;
  643.         if ((flags & (MF_ODWORD|MF_ODLONG)) == 0)
  644.         flags |= MF_ODWORD;
  645.     }
  646.     }
  647.  
  648.     ea->Reg1 = baseReg;
  649.  
  650.     if ((flags & MF_INDEX) == 0) {
  651.     if (baseReg == 16) {
  652.         ea->Mode1 = AB_OFFPC;
  653.         ea->Mode2 = (ea->ISize & ISF_INSTBYTE) ? AB_BBRANCH : AB_WBRANCH;
  654.     } else {
  655.         ea->Mode1 = AB_OFFAN;
  656.     }
  657.     } else {
  658.     if (flags & (MF_MEMIND|MF_ODLONG|MF_ODWORD|MF_BDLONG|MF_BDWORD)) {
  659.         ea->ExtWord |= EXTF_FULL;
  660.  
  661.         if (flags & MF_ODWORD)
  662.         ea->ExtWord |= EXTF_ODWORD;
  663.         else if (flags & MF_ODLONG)
  664.         ea->ExtWord |= EXTF_ODLONG;
  665.         else
  666.         ea->ExtWord |= EXTF_ODNULL;
  667.  
  668.         if (flags & MF_BDWORD)
  669.         ea->ExtWord |= EXTF_BDWORD;
  670.         else if (flags & MF_BDLONG)
  671.         ea->ExtWord |= EXTF_BDLONG;
  672.         else
  673.         ea->ExtWord |= EXTF_BDNULL;
  674.  
  675.         if ((flags & MF_MEMINDPOS) && idxReg >= 0)
  676.         ea->ExtWord |= EXTF_MEMIND;
  677.         if ((flags & MF_MEMIND) == 0)       /*  no memory indirect */
  678.         ea->ExtWord &= ~EXTF_ODMASK;
  679.     }
  680.     if (baseReg == 16) {
  681.         ea->Mode1 = AB_OFFIDXPC;
  682.     } else if (baseReg == 17) {
  683.         ea->Mode1 = AB_OFFIDXPC;
  684.         ea->ExtWord |= EXTF_NOBREG | EXTF_FULL;    /*  ZPC */
  685.     } else {
  686.         ea->Mode1 = AB_OFFIDX;
  687.         if (baseReg < 0)
  688.         ea->ExtWord |= EXTF_NOBREG | EXTF_FULL;
  689.         ea->Reg1 = baseReg;
  690.     }
  691.     if (idxReg < 0) {
  692.         ea->ExtWord |= EXTF_NOIDX | EXTF_FULL;
  693.     } else if (idxReg < RB_AREG) {
  694.         ea->ExtWord |= idxReg << 12;
  695.     } else {
  696.         ea->ExtWord |= ((idxReg - RB_AREG) << 12) | EXTF_AREG;
  697.     }
  698.     }
  699.     if ((flags & MF_INDEX020) && !MC68020)
  700.     cerror(EWARN_68020);
  701.     if (*str != ')')
  702.     syntax(9);
  703.     return(str + 1);
  704. }
  705.  
  706. char *
  707. ParseRegList(str, pmask)
  708. char *str;
  709. uword *pmask;
  710. {
  711.     long mask = 0;
  712.     short regno = -1;
  713.     short range = 0;
  714.  
  715.     while (*str && *str != ' ' && *str != 9) {
  716.     if (range) {
  717.         short reg2 = -1;
  718.  
  719.         if (*str == 'D' || *str == 'd')
  720.         reg2 = str[1] - '0' + RB_DREG;
  721.         else if (*str == 'A' || *str == 'a')
  722.         reg2 = str[1] - '0' + RB_AREG;
  723.         else
  724.         cerror(EERROR_BAD_REG_SPEC);
  725.         while (regno <= reg2)
  726.         mask |= 1 << regno++;
  727.         regno = -1;
  728.         range = 0;
  729.         str += 2;
  730.         if (*str == '/')
  731.         ++str;
  732.     } else if (regno < 0) {
  733.         if (*str == ',')
  734.         break;
  735.         if (*str == 'D' || *str == 'd')
  736.         regno = str[1] - '0' + RB_DREG;
  737.         else if (*str == 'A' || *str == 'a')
  738.         regno = str[1] - '0' + RB_AREG;
  739.         else
  740.         cerror(EERROR_BAD_REG_SPEC);
  741.         str += 2;
  742.     } else {
  743.         if (*str == ',')
  744.         break;
  745.         if (*str == '/') {
  746.         mask |= 1 << regno;
  747.         regno = -1;
  748.         } else if (*str == '-') {
  749.         range = 1;
  750.         } else {
  751.         cerror(EERROR_BAD_REG_SPEC);
  752.         }
  753.         ++str;
  754.     }
  755.     }
  756.     if (range == 1)
  757.     cerror(EERROR_BAD_REG_SPEC);
  758.     if (regno >= 0)
  759.     mask |= 1 << regno;
  760.     *pmask = mask;
  761.     return(str);
  762. }
  763.  
  764.  
  765. char *
  766. ParseBinaryConst(str, pv)
  767. char *str;
  768. long *pv;
  769. {
  770.     long v = 0;
  771.  
  772.     for (;;) {
  773.     if (*str == '0' || *str == '1')
  774.         v = (v << 1) | (*str - '0');
  775.     else if (*str != '.')
  776.         break;
  777.     ++str;
  778.     }
  779.     *pv = v;
  780.     return(str);
  781. }
  782.  
  783. char *
  784. ParseHexConst(str, pv)
  785. char *str;
  786. long *pv;
  787. {
  788.     long v = 0;
  789.  
  790.     for (;;) {
  791.     if (*str >= '0' && *str <= '9') {
  792.         v = (v << 4) + *str - '0';
  793.     } else if (*str >= 'a' && *str <= 'f') {
  794.         v = (v << 4) + *str - 'a' + 10;
  795.     } else if (*str >= 'A' && *str <= 'F') {
  796.         v = (v << 4) + *str - 'A' + 10;
  797.     } else
  798.         break;
  799.     ++str;
  800.     }
  801.     *pv = v;
  802.     return(str);
  803. }
  804.  
  805. char *
  806. ParseIntConst(str, pv)
  807. char *str;
  808. long *pv;
  809. {
  810.     long v = 0;
  811.     while (*str >= '0' && *str <= '9')
  812.     v = v * 10 + *str++ - '0';
  813.     *pv = v;
  814.     return(str);
  815. }
  816.  
  817. char *
  818. ParseLabel(str, plab, showerr)
  819. char *str;
  820. Label **plab;
  821. int showerr;
  822. {
  823.     char *base = str;
  824.     char c;
  825.     Label *lab;
  826.  
  827.     while (*str == '@' || *str == '_' || (*str >= 'a' && *str <= 'z') || (*str >= 'A' && *str <= 'Z') || (*str >= '0' && *str <= '9'))
  828.     ++str;
  829.     c = *str;
  830.     *str = 0;
  831.     lab = FindLabel(base);
  832.     if (lab == NULL && showerr)
  833.     cerror(EERROR_UNDEFINED_LABEL, base);
  834.     *str = c;
  835.     *plab = lab;
  836.     return(str);
  837. }
  838.  
  839. int
  840. CheckRegister(ptr)
  841. char *ptr;
  842. {
  843.     int reg = 0;
  844.  
  845.     switch(*ptr) {
  846.     case 'a':
  847.     case 'A':
  848.     reg = RB_AREG;
  849.     case 'd':
  850.     case 'D':
  851.     reg += ptr[1] - '0';
  852.     if (ptr[1] >= '0' && ptr[1] <= '7') {
  853. almost:
  854.         if (ptr[2] == 0 || ptr[2] == '.' || ptr[2] == ']' || ptr[2] == ')' || ptr[2] == ',')
  855.         return(reg);
  856.     }
  857.     break;
  858.     case 'p':
  859.     case 'P':
  860.     reg = 16;
  861.     if (ptr[1] == 'c' || ptr[1] == 'C')
  862.         goto almost;
  863.     break;
  864.     case 's':
  865.     case 'S':
  866.     reg = RB_AREG + 7;
  867.     if (ptr[1] == 'p' || ptr[1] == 'P')
  868.         goto almost;
  869.     break;
  870.     case 'z':
  871.     case 'Z':
  872.     reg = 17;
  873.     ++ptr;
  874.     if (strnicmp(ptr, "pc", 2) == 0)
  875.         goto almost;
  876.     break;
  877.     }
  878.     return(-1);
  879. }
  880.  
  881.  
  882. #ifdef NOTDEF
  883.  
  884. char *
  885. ParseDumpString(mc, str, termc)
  886. MachCtx *mc;
  887. char *str;
  888. char termc;
  889. {
  890.     char buf[64];
  891.     short i = 0;
  892.  
  893.     while (*str && *str != termc) {
  894.     buf[i++] = *str;
  895.     if (i == sizeof(buf)) {
  896.         DumpSectionData(mc->Sect, buf, i);
  897.         i = 0;
  898.     }
  899.     ++str;
  900.     }
  901.     if (i)
  902.     DumpSectionData(mc->Sect, buf, i);
  903.     if (*str)
  904.     return(str+1);
  905.     cerror(EERROR_EXPECTED_TERMINATING, termc);
  906.     return(str);
  907. }
  908. #endif
  909.